home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / 3D / WRENDANI.C < prev   
Encoding:
C/C++ Source or Header  |  1996-08-03  |  12.0 KB  |  576 lines

  1. #include <math.h>
  2. #include "wrend.h"
  3.  
  4. /* 3D object translation, rotation, scaling, and animation
  5.    Copyright 1995 Egerter Software */
  6.  
  7.  
  8.  
  9. void set_object_pivot (object_3d *obj, float x, float y, float z)
  10. {
  11.  obj->pivotx = x;
  12.  obj->pivoty = y;
  13.  obj->pivotz = z;
  14.  
  15.  obj->rotatex = 0;
  16.  obj->rotatey = 0;
  17.  obj->rotatez = 0;
  18.  
  19.  obj->scalex = 1;
  20.  obj->scaley = 1;
  21.  obj->scalez = 1;
  22. }
  23.  
  24.  
  25. void translate_object (object_3d *obj, vertex *pts, float x, float y, float z)
  26. {
  27. int start, finish;
  28. int poly, point;
  29. triangle_3d *ptr;
  30.  
  31.   /* Translate the center of each polygon */
  32.   /*
  33.   start = obj->start_poly;
  34.   finish = obj->end_poly;
  35.   for (poly = start; poly <= finish; poly++)
  36.   {
  37.    ptr = &polylist[poly];
  38.    ptr->center.x += x;
  39.    ptr->center.y += y;
  40.    ptr->center.z += z;
  41.   }
  42.  */
  43.   /* Translate each vertex in this object */
  44.   start = obj->startpoints;
  45.   finish = start + obj->points - 1;
  46.  
  47.   for (point = start; point <= finish; point++)
  48.   {
  49.    pts[point].local.x += x;
  50.    pts[point].local.y += y;
  51.    pts[point].local.z += z;
  52.   }
  53.  
  54.  obj->pivotx += x;
  55.  obj->pivoty += y;
  56.  obj->pivotz += z;
  57. }
  58.  
  59.  
  60. void scale_object (object_3d *obj, vertex *pts, float x, float y, float z,
  61.            float pivotx, float pivoty, float pivotz)
  62. {
  63. int start, finish;
  64. int point;
  65. vertex *pt;
  66.  
  67.  /* Translate each vertex in this object */
  68.  start = obj->startpoints;
  69.  finish = start + obj->points - 1;
  70.  
  71.  for (point = start; point <= finish; point++)
  72.   {
  73.    pt = &pts[point];
  74.  
  75.    pt->local.x = (pt->local.x - pivotx) * x + pivotx;
  76.    pt->local.y = (pt->local.y - pivoty) * y + pivoty;
  77.    pt->local.z = (pt->local.z - pivotz) * z + pivotz;
  78.   }
  79.  
  80. }
  81.    
  82.  
  83. void rotate_point (float *ptx,    float *pty,    float *ptz, 
  84.            float x,      float y,      float z,
  85.            float pivotx, float pivoty, float pivotz)
  86. {
  87. float i,j,k;
  88. float rotx, roty, rotz;
  89. float xo, yo, zo;
  90. float xcos, xsin, ycos, ysin, zcos, zsin;
  91.  
  92.  xcos = cos (x * M_PI / 180.0);
  93.  xsin = sin (x * M_PI / 180.0);
  94.  ycos = cos (y * M_PI / 180.0);
  95.  ysin = sin (y * M_PI / 180.0);
  96.  zcos = cos (z * M_PI / 180.0);
  97.  zsin = sin (z * M_PI / 180.0);
  98.  
  99.  xo = (*ptx) - pivotx;
  100.  yo = (*pty) - pivoty;
  101.  zo = (*ptz) - pivotz;
  102.  
  103.  /* Z axis */
  104.  i = (xo * zcos - yo * zsin);
  105.  j = (xo * zsin + yo * zcos);
  106.  k = zo;
  107.  
  108.  /* X axis */
  109.  roty = (j * xcos - k * xsin);
  110.  rotz = (j * xsin + k * xcos);
  111.  k = rotz;
  112.  
  113.  /* Y axis */
  114.  rotx = (k * ysin + i * ycos);
  115.  rotz = (k * ycos - i * ysin);
  116.  
  117.  *ptx = rotx + pivotx;
  118.  *pty = roty + pivoty;
  119.  *ptz = rotz + pivotz;
  120.   
  121.    
  122. }
  123.  
  124.  
  125.  
  126.  
  127. void rotate_object_with_children (object_3d *obj, vertex *pts, float x, float y, float z,
  128.                   float pivotx, float pivoty, float pivotz)
  129. {
  130. float i,j,k;
  131. float rotx, roty, rotz;
  132. int start, finish;
  133. int point, poly;
  134. float xo, yo, zo;
  135. float xcos, xsin, ycos, ysin, zcos, zsin;
  136. vertex *pt;
  137. triangle_3d *ptr;
  138. int child;
  139. object_3d *childptr;
  140.  
  141.  xcos = cos (x * M_PI / 180.0);
  142.  xsin = sin (x * M_PI / 180.0);
  143.  ycos = cos (y * M_PI / 180.0);
  144.  ysin = sin (y * M_PI / 180.0);
  145.  zcos = cos (z * M_PI / 180.0);
  146.  zsin = sin (z * M_PI / 180.0);
  147.  
  148.  /* Rotate each vertex in this object */
  149.  start = obj->startpoints;
  150.  finish = start + obj->points - 1;
  151.  
  152.  for (point = start; point <= finish; point++)
  153.   {
  154.    /* Rotate the vertex */
  155.    pt = &pts[point];
  156.  
  157.    xo = pt->local.x - pivotx;
  158.    yo = pt->local.y - pivoty;
  159.    zo = pt->local.z - pivotz;
  160.  
  161.    /* Z axis */
  162.    i = (xo * zcos - yo * zsin);
  163.    j = (xo * zsin + yo * zcos);
  164.    k = zo;
  165.  
  166.    /* X axis */
  167.    roty = (j * xcos - k * xsin);
  168.    rotz = (j * xsin + k * xcos);
  169.    k = rotz;
  170.  
  171.    /* Y axis */
  172.    rotx = (k * ysin + i * ycos);
  173.    rotz = (k * ycos - i * ysin);
  174.  
  175.    pt->local.x = rotx + pivotx;
  176.    pt->local.y = roty + pivoty;
  177.    pt->local.z = rotz + pivotz;
  178.   
  179.    
  180.    /* Rotate the normal */
  181.    xo = pt->normal.x;
  182.    yo = pt->normal.y;
  183.    zo = pt->normal.z;
  184.  
  185.    /* Z axis */
  186.    i = (xo * zcos - yo * zsin);
  187.    j = (xo * zsin + yo * zcos);
  188.    k = zo;
  189.  
  190.    /* X axis */
  191.    roty = (j * xcos - k * xsin);
  192.    rotz = (j * xsin + k * xcos);
  193.    k = rotz;
  194.  
  195.    /* Y axis */
  196.    rotx = (k * ysin + i * ycos);
  197.    rotz = (k * ycos - i * ysin);
  198.  
  199.    pt->normal.x = rotx;
  200.    pt->normal.y = roty;
  201.    pt->normal.z = rotz;
  202.   
  203.   }
  204.  
  205.  
  206.  start = obj->start_poly;
  207.  finish = obj->end_poly;
  208.  
  209.  for (poly = start; poly <= finish; poly++)
  210.   {
  211.    ptr = &polylist[poly];
  212.  
  213.    /* Rotate the normal of each polygon */
  214.    xo = ptr->normal.x;
  215.    yo = ptr->normal.y;
  216.    zo = ptr->normal.z;
  217.  
  218.    /* Z axis */
  219.    i = (xo * zcos - yo * zsin);
  220.    j = (xo * zsin + yo * zcos);
  221.    k = zo;
  222.  
  223.    /* X axis */
  224.    roty = (j * xcos - k * xsin);
  225.    rotz = (j * xsin + k * xcos);
  226.    k = rotz;
  227.  
  228.    /* Y axis */
  229.    rotx = (k * ysin + i * ycos);
  230.    rotz = (k * ycos - i * ysin);
  231.  
  232.    ptr->normal.x = rotx;
  233.    ptr->normal.y = roty;
  234.    ptr->normal.z = rotz;
  235.   }
  236.  
  237.    
  238.  if (obj->maxchild > -1)  
  239.   {
  240.    for (child = 0; child <= obj->maxchild; child++)
  241.     {
  242.      childptr = &objectlist[obj->children[child]];
  243.      rotate_point (&childptr->pivotx, &childptr->pivoty, &childptr->pivotz, 
  244.             x, y, z, pivotx, pivoty, pivotz);
  245.      rotate_object_with_children (childptr, pts, x, y, z, pivotx, pivoty, 
  246.     pivotz);
  247.     }
  248.   }
  249. }
  250.  
  251.  
  252. void rotate_object (object_3d *obj, vertex *pts, float x, float y, float z,
  253.             float pivotx, float pivoty, float pivotz)
  254. {
  255. float i,j,k;
  256. float rotx, roty, rotz;
  257. int start, finish;
  258. int point, poly;
  259. float xo, yo, zo;
  260. float xcos, xsin, ycos, ysin, zcos, zsin;
  261. vertex *pt;
  262. triangle_3d *ptr;
  263.  
  264.  xcos = cos (x * M_PI / 180.0);
  265.  xsin = sin (x * M_PI / 180.0);
  266.  ycos = cos (y * M_PI / 180.0);
  267.  ysin = sin (y * M_PI / 180.0);
  268.  zcos = cos (z * M_PI / 180.0);
  269.  zsin = sin (z * M_PI / 180.0);
  270.  
  271.  
  272.  //obj->rotatex += x;
  273.  //obj->rotatey += y;
  274.  //obj->rotatez += z;
  275.  
  276.  /* Rotate each vertex in this object */
  277.  start = obj->startpoints;
  278.  finish = start + obj->points - 1;
  279.  
  280.  for (point = start; point <= finish; point++)
  281.   {
  282.    /* Rotate the vertex */
  283.    pt = &pts[point];
  284.  
  285.    xo = pt->local.x - pivotx;
  286.    yo = pt->local.y - pivoty;
  287.    zo = pt->local.z - pivotz;
  288.  
  289.    /* Z axis */
  290.    i = (xo * zcos - yo * zsin);
  291.    j = (xo * zsin + yo * zcos);
  292.    k = zo;
  293.  
  294.    /* X axis */
  295.    roty = (j * xcos - k * xsin);
  296.    rotz = (j * xsin + k * xcos);
  297.    k = rotz;
  298.  
  299.    /* Y axis */
  300.    rotx = (k * ysin + i * ycos);
  301.    rotz = (k * ycos - i * ysin);
  302.  
  303.    pt->local.x = rotx + pivotx;
  304.    pt->local.y = roty + pivoty;
  305.    pt->local.z = rotz + pivotz;
  306.   
  307.    
  308.    /* Rotate the normal */
  309.    xo = pt->normal.x;
  310.    yo = pt->normal.y;
  311.    zo = pt->normal.z;
  312.  
  313.    /* Z axis */
  314.    i = (xo * zcos - yo * zsin);
  315.    j = (xo * zsin + yo * zcos);
  316.    k = zo;
  317.  
  318.    /* X axis */
  319.    roty = (j * xcos - k * xsin);
  320.    rotz = (j * xsin + k * xcos);
  321.    k = rotz;
  322.  
  323.    /* Y axis */
  324.    rotx = (k * ysin + i * ycos);
  325.    rotz = (k * ycos - i * ysin);
  326.  
  327.    pt->normal.x = rotx;
  328.    pt->normal.y = roty;
  329.    pt->normal.z = rotz;
  330.   
  331.   }
  332.  
  333.  
  334.  start = obj->start_poly;
  335.  finish = obj->end_poly;
  336.  
  337.  for (poly = start; poly <= finish; poly++)
  338.   {
  339.    ptr = &polylist[poly];
  340.  
  341.    /* Rotate the normal of each polygon */
  342.    xo = ptr->normal.x;
  343.    yo = ptr->normal.y;
  344.    zo = ptr->normal.z;
  345.  
  346.    /* Z axis */
  347.    i = (xo * zcos - yo * zsin);
  348.    j = (xo * zsin + yo * zcos);
  349.    k = zo;
  350.  
  351.    /* X axis */
  352.    roty = (j * xcos - k * xsin);
  353.    rotz = (j * xsin + k * xcos);
  354.    k = rotz;
  355.  
  356.    /* Y axis */
  357.    rotx = (k * ysin + i * ycos);
  358.    rotz = (k * ycos - i * ysin);
  359.  
  360.    ptr->normal.x = rotx;
  361.    ptr->normal.y = roty;
  362.    ptr->normal.z = rotz;
  363.   }
  364. }
  365.  
  366.  
  367.  
  368. /* Considerations:
  369.   - multiple keys per frame, for different objects
  370.   - additive elements due to hierarchy
  371.   - does scale affect children objects?
  372.  
  373.   - idea:
  374.     - store additive amounts in object structure
  375.     - for each keyframe, calculate new values and store
  376.      into obj struct
  377.  
  378.     - for each frame of animation
  379.     - set elements for each objects to 0
  380.     - for each object,
  381.     add elements from obj struct
  382.     for each child of object
  383.       add elements from parent
  384.     - for each object
  385.       transform if needed
  386.  
  387.  
  388.  
  389. */
  390.  
  391.  
  392.  
  393.  
  394. void setup_nextframe (object_3d *obj)
  395. {
  396. int numframes;
  397. int searchframe;
  398. int frame;
  399. float tx, ty, tz,   rx, ry, rz,  sx, sy, sz;
  400. float cx, cy, cz;
  401. keydata *keyprev;
  402. keydata *key;
  403. int advance;
  404.  
  405.  advance = 0;
  406.  frame = obj->currentframe;
  407.  
  408.  cx = obj->pivotx;
  409.  cy = obj->pivoty;
  410.  cz = obj->pivotz;
  411.  
  412.  key = &obj->keylist[frame];
  413.  keyprev = key; 
  414.  
  415.  if ((key->update_translation) && (obj->tstepsleft == -1))
  416.   {
  417.    searchframe = frame+1;
  418.    while ((obj->keylist[searchframe].update_translation == 0) 
  419.       && (searchframe < obj->maxframe))
  420.      searchframe++;
  421.  
  422.    if (obj->keylist[searchframe].update_translation == 1)
  423.    {
  424.     numframes = obj->keylist[searchframe].framenumber -
  425.         obj->keylist[frame].framenumber;
  426.     obj->tstepsleft = numframes;
  427.    
  428.     key = &obj->keylist[searchframe];
  429.  
  430.     tx = (key->tx - keyprev->tx) / numframes;
  431.     ty = (key->ty - keyprev->ty) / numframes;
  432.     tz = (key->tz - keyprev->tz) / numframes;
  433.     obj->translatex = tx;
  434.     obj->translatey = ty;
  435.     obj->translatez = tz;
  436.     advance = 1;
  437.    }
  438.    else
  439.    if (obj->tstepsleft == 0)
  440.      obj->tstepsleft = -1;
  441.  
  442.   }
  443.  else
  444.   {
  445.    if (obj->tstepsleft == 0)
  446.      obj->tstepsleft = -1;
  447.   }
  448.  
  449.  /*if (key->update_scale)
  450.   {
  451.    sx = 1 + (key->sx / numframes);
  452.    sy = 1 + (key->sy / numframes);
  453.    sz = 1 + (key->sz / numframes);
  454.    obj->scalex = sx;
  455.    obj->scaley = sy;
  456.    obj->scalez = sz;
  457.   }*/
  458.  
  459.  
  460.  if ((key->update_rotation) && (obj->rstepsleft == -1))
  461.   {
  462.    searchframe = frame+1;
  463.    while ((obj->keylist[searchframe].update_rotation == 0) 
  464.       && (searchframe < obj->maxframe))
  465.      searchframe++;
  466.    
  467.    if (obj->keylist[searchframe].update_rotation == 1)
  468.    {
  469.     numframes = obj->keylist[searchframe].framenumber -
  470.         obj->keylist[frame].framenumber;
  471.     obj->rstepsleft = numframes;
  472.  
  473.     key = &obj->keylist[searchframe];
  474.    
  475.     rx = (-key->rx) / numframes;
  476.     ry = (-key->ry) / numframes;
  477.     rz = (-key->rz) / numframes;
  478.     obj->rotatex = rx;
  479.     obj->rotatey = ry;
  480.     obj->rotatez = rz;
  481.     advance = 1;
  482.    }
  483.    else
  484.    if (obj->rstepsleft == 0)
  485.      obj->rstepsleft = -1;
  486.  
  487.   }
  488.  else
  489.   {
  490.    if (obj->rstepsleft == 0)
  491.      obj->rstepsleft = -1;
  492.   }
  493.  
  494.  if (advance) 
  495.   {
  496.    obj->currentframe++; 
  497.    if (obj->currentframe == obj->maxframe)
  498.      obj->currentframe = 0;
  499.   }
  500. }
  501.  
  502.  
  503. void animate_object (object_3d *obj, vertex *pts)
  504. {
  505. object_3d *obj2;
  506. object_3d *ch;
  507. int child;
  508. float px, py, pz,  tx, ty, tz,  rx, ry, rz,  sx, sy, sz;
  509.  
  510.  px = obj->pivotx;
  511.  py = obj->pivoty;
  512.  pz = obj->pivotz;
  513.  sx = obj->scalex;
  514.  sy = obj->scaley;
  515.  sz = obj->scalez;
  516.  rx = obj->rotatex;
  517.  ry = obj->rotatey;
  518.  rz = obj->rotatez;
  519.  tx = obj->translatex;
  520.  ty = obj->translatey;
  521.  tz = obj->translatez;
  522.  
  523. /* if ((tx != 0) || (ty != 0) || (tz != 0))
  524.   {
  525.    translate_object (obj, pts, tx, ty, tz);
  526.    
  527.    obj2 = obj;
  528.    while (obj2->numchildren > 0)
  529.     {
  530.      ch = &objectlist[obj2->children[0]];
  531.      translate_object (ch, pts, tx, ty, tz);
  532.      obj2 = ch;
  533.     }
  534.   }
  535.   */
  536. /* if ((sx != 1) || (sy != 1) || (sz != 1))
  537.   {
  538.    scale_object (obj, pts, sx, sy, sz, px, py, pz);
  539.    if (obj->numchildren > 0)
  540.     for (child = 0; child < obj->numchildren; child++)
  541.      scale_object (&objectlist[obj->children[child]], pts, sx, sy, sz, px, py, pz);
  542.   }*/
  543.  
  544.  if ((rx != 0) || (ry != 0) || (rz != 0))
  545.   {
  546.    rotate_object_with_children (obj, pts, rx, ry, rz, px, py, pz);
  547.   }
  548. }
  549.  
  550.  
  551.  
  552. void animate_objects (vertex *pts)
  553. {
  554. int objnum; /* Object number */
  555. object_3d *obj; /* ptr to the object */
  556.  
  557.  for (objnum = 0; objnum < totalobjects; objnum++)
  558.   {
  559.    obj = &objectlist[objnum];
  560.    if (obj->maxframe > -1)
  561.      {   
  562.       if ((obj->tstepsleft < 0) || (obj->rstepsleft < 0))
  563.     setup_nextframe (obj);
  564.       if ((obj->tstepsleft > -1) || (obj->rstepsleft > -1))
  565.     {
  566.      animate_object (obj, pts);
  567.      if (obj->tstepsleft >= 0)
  568.        obj->tstepsleft--;
  569.      if (obj->rstepsleft >= 0)
  570.        obj->rstepsleft--;
  571.     }
  572.        
  573.      }
  574.   }
  575. }
  576.